﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using Microsoft.Practices.Composite.Regions;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Composite.Events;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Controls;
using Microsoft.Practices.Composite.Presentation.Commands;

namespace Infrastructure.WpfClient.Views.Master
{
    //Navigation Interface only 
    public abstract class MasterPresenterController : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public System.Windows.Navigation.NavigationService NavigationService { get; set; }
        public void InvokePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
        public abstract void Run();

        
    }
    public abstract class MasterPresenter : INotifyPropertyChanged, IDisposable
    {
        protected object _View;
        public string TitleView { get; set; }
        public System.Threading.SynchronizationContext SyncContext { get; protected set; } 
        public event PropertyChangedEventHandler PropertyChanged;
        public DelegateCommand<object> CloseCommand { get; set; }
        
        public void InvokePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null) 
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));         
        }
        public MasterPresenter(IUnityContainer container)
        {
            this.TitleView = "";
            this.SyncContext = System.Threading.SynchronizationContext.Current;
            this.CloseCommand = new DelegateCommand<object>(C => this.OnViewClose());
            this.EventAggregator = container.Resolve<IEventAggregator>();
            var logout = this.EventAggregator.GetEvent<GlobalEvents.LogOutApplicationEvent>();
            logout.Subscribe(OnLogoutApplication);
        }
        public virtual void OnLogoutApplication(object param)
        {
            this.OnViewClose();
        }

   
        [Dependency]
        public IUnityContainer ContainerService { get; set; }
        
        public IEventAggregator EventAggregator { get; set; }


        
        public virtual void OnViewReady() 
        {

        }
        public virtual void OnViewClose()
        {
            var closeevent = this.EventAggregator.GetEvent<GlobalEvents.CloseViewEvent>();
            closeevent.Publish(this._View);
        }
        public virtual void Dispose()
        {
            this._View = null;
        }
        public virtual bool IsValid(DependencyObject parent)
        {
            // Validate all the bindings on the parent
            bool valid = true;
            LocalValueEnumerator localValues = parent.GetLocalValueEnumerator();
            while (localValues.MoveNext())
            {
                LocalValueEntry entry = localValues.Current;
                if (BindingOperations.IsDataBound(parent, entry.Property))
                {
                    Binding binding = BindingOperations.GetBinding(parent, entry.Property);
                    if (binding.ValidationRules.Count > 0)
                    {
                        BindingExpression expression = BindingOperations.GetBindingExpression(parent, entry.Property);
                        expression.UpdateSource();

                        if (expression.HasError) valid = false;
                    }
                }
            }
            System.Collections.IEnumerable children = LogicalTreeHelper.GetChildren(parent);
            foreach (object obj in children)
            {
                if (obj is DependencyObject)
                {
                    DependencyObject child = (DependencyObject)obj;
                    if (!IsValid(child)) { valid = false; }
                }
            }
            return valid;
        }
    }
    public abstract class MasterPresenter<TView> : MasterPresenter
    {
        public TView View { get { return (TView)this._View; } set { this._View = value; } }

        
        
        public MasterPresenter(IUnityContainer container):base(container)
        {

        
        }              
    }


}
